<template>
	<Tree :data="data" @on-check-change="handleCheckSelect" v-on="parent.$listeners" v-bind="parent.$attrs" :load-data="loadDataCallback" show-checkbox></Tree>
</template>

<script>
import Emitter from 'iview/src/mixins/emitter.js';

const arrayEqual = (arr1, arr2) => {
	// 判断数组的长度
	if (arr1.length !== arr2.length) {
		return false;
	} else {
		// 循环遍历数组的值进行比较
		for (let i = 0; i < arr1.length; i++) {
			if (arr1[i] !== arr2[i]) {
				return false;
			}
		}
		return true;
	}
};

export default {
	name: 'TreeSelectTree',
	mixins: [Emitter],
	props: {
		data: {
			type: Array,
			default: () => []
		},
		selectedArray: {
			type: Array,
			default: () => []
		},
		loadData: Function
	},
	data() {
		return {
			flatDic: {},
			checkedArray: []
		};
	},
	inject: ['parent'],
	computed: {
		expandAll() {
			return this.parent.$attrs['expand-all'];
		}
	},
	watch: {
		data(newData, oldVal) {
			this.updateFlagDic(newData);
			let selectArray = [];
			this.selectedArray.forEach(id => {
				if (id in this.flatDic) selectArray.push(id);
			});
			this.$emit(
				'on-check',
				selectArray.map(id => this.flatDic[id])
			);
			if (this.expandAll) this.checkData(newData, false, true);
		},
		selectedArray(newVal, oldVal) {
			if (arrayEqual(newVal, oldVal)) return;
			const filtedNewVal = newVal.filter(id => id in this.flatDic);
			this.$emit(
				'on-check',
				filtedNewVal.map(id => this.flatDic[id])
			);
			this.$emit('on-clear');
			this.$nextTick(() => {
				this.checkData(this.data, true);
			});
		}
	},
	methods: {
		checkEmit(value, label) {
			this.dispatch('iSelect', 'on-select-selected', {
				value,
				label
			});
			this.$emit('on-select-selected', {
				value,
				label
			});
		},
		updateFlagDic(newData) {
			let newFlagDic = {};
			this.setFlagDic(newData, item => {
				newFlagDic[item.id] = item;
			});
			this.flatDic = newFlagDic;
		},
		setFlagDic(data, callback) {
			data.forEach(item => {
				if (item.children && item.children.length) {
					this.setFlagDic(item.children, callback);
				}
				callback(item);
			});
		},
		handleCheckSelect(selectArray, selectItem) {
			this.$emit('on-check', selectArray);
			this.parent.$emit('on-change', selectArray);
		},
		checkData(data, emit, expandAll) {
			data.forEach(item => {
				if (this.selectedArray.includes(item.id)) {
					this.$set(item, 'checked', true);
					this.checkedArray.push(item);
					if (emit) this.checkEmit(item.id, item.title);
				} else this.$set(item, 'checked', false);
				if (item.children && item.children.length) {
					if (this.expandAll && expandAll) this.$set(item, 'expand', true);
					this.checkData(item.children, emit, expandAll);
				}
			});
		},
		loadDataCallback(item, callback) {
			this.loadData(item, data => {
				return (() => {
					callback(data);
					this.updateFlagDic(this.data);
				})(data);
			});
		}
	},
	mounted() {
		this.checkData(this.data, false, true);
		this.$nextTick(() => {
			this.$emit('on-check', this.checkedArray);
		});
	}
};
</script>

<style></style>
